﻿using System;

using System.Collections.Generic;

namespace Microsoft.Windows.Controls.Internals {

    internal class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue> {
        private IDictionary<TKey, TValue> _original;

        public ObservableDictionary() {
            _original = new Dictionary<TKey, TValue>();
        }

        public ObservableDictionary(IDictionary<TKey, TValue> original) {
            if (original != null)
                throw new ArgumentNullException("original");
            _original = original;
        }

        public event EventHandler Changed;

        protected void OnChange() {
            if (Changed != null)
                Changed(this, EventArgs.Empty);
        }

        #region IDictionary<TKey,TValue> Members

        public void Add(TKey key, TValue value) {
            _original.Add(key, value);
            OnChange();
        }

        public bool ContainsKey(TKey key) {
            return _original.ContainsKey(key);
        }

        public ICollection<TKey> Keys {
            get {
                return _original.Keys;
            }
        }

        public bool Remove(TKey key) {
            var result = _original.Remove(key);
            if (result) OnChange();
            return result;
        }

        public bool TryGetValue(TKey key, out TValue value) {
            return _original.TryGetValue(key, out value);
        }

        public ICollection<TValue> Values {
            get {
                return _original.Values;
            }
        }

        public TValue this[TKey key] {
            get {
                return _original[key];
            }
            set {
                _original[key] = value;
            }
        }

        #endregion

        #region ICollection<KeyValuePair<TKey,TValue>> Members

        public void Add(KeyValuePair<TKey, TValue> item) {
            _original.Add(item);
            OnChange();
        }

        public void Clear() {
            _original.Clear();
            OnChange();
        }

        public bool Contains(KeyValuePair<TKey, TValue> item) {
            return _original.Contains(item);
        }

        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
            _original.CopyTo(array, arrayIndex);
        }

        public int Count {
            get { return _original.Count; }
        }

        public bool IsReadOnly {
            get { return _original.IsReadOnly; }
        }

        public bool Remove(KeyValuePair<TKey, TValue> item) {
            var result = Remove(item);
            if (result) OnChange();
            return result;
        }

        #endregion

        #region IEnumerable<KeyValuePair<TKey,TValue>> Members

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
            return _original.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return _original.GetEnumerator();
        }

        #endregion
    }
}
